/*
 * Copyright 2025 arisgo@163.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.arisgo.cloud.shiro.config;

import com.arisgo.cloud.shiro.filter.JwtFilter;
import com.arisgo.cloud.shiro.realm.ShiroRealm;
import jakarta.servlet.Filter;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author Arisgo
 * @since 2024/3/16
 */
@Configuration(proxyBeanMethods = false)
public class ShiroConfiguration {

    @Bean
    @Lazy
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactory = new ShiroFilterFactoryBean();
        // 设置filter安全管理器
        shiroFilterFactory.setSecurityManager(securityManager);
        // 默认认证登陆界面，认证不通过时跳转
        shiroFilterFactory.setLoginUrl("/login");

        // 添加过滤器
        Map<String, Filter> filterMap = new LinkedHashMap<>();
        filterMap.put("jwt", new JwtFilter());
        shiroFilterFactory.setFilters(filterMap);

        // 配置系统受限资源
        Map<String, String> restrictMap = new LinkedHashMap<>();
        restrictMap.put("/login", "anon");
        restrictMap.put("/logout", "anon");
        restrictMap.put("/register", "anon");
        restrictMap.put("/**", "jwt");

        shiroFilterFactory.setFilterChainDefinitionMap(restrictMap);
        return shiroFilterFactory;
    }

    @Bean
    @Lazy
    public DefaultWebSecurityManager securityManager(ShiroRealm shiroRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm
        securityManager.setRealm(shiroRealm);
        // 关闭shiro自带的session
        DefaultSessionStorageEvaluator evaluator = new DefaultSessionStorageEvaluator();
        evaluator.setSessionStorageEnabled(false);
        // 设置subject
        DefaultSubjectDAO subject = new DefaultSubjectDAO();
        subject.setSessionStorageEvaluator(evaluator);
        securityManager.setSubjectDAO(subject);
        return securityManager;
    }

}
